"""
实现斐波那契函数(for循环, while循环)
如果遇到可以转换为int类型的参数, 则转换, 否则抛出自定义异常ParamsTypeError
斐波那契数列指的是这样一个数列：0、1、1、2、3、5、8、13、21、34、……
在数学上，斐波那契数列以如下被以递推的方法定义：F(0)=0，F(1)=1, F(n)=F(n - 1)+F(n - 2)（n ≥ 2，n ∈ N*）
"""


# 自定义异常
class ParamsTypeError(Exception):
    pass


# for循环实现  n:斐波那契数列第n项
def fib_for(n):
    n0, n1, n2 = 0, 1, 1
    try:
        format_n = int(n)
    except Exception as e:
        raise ParamsTypeError(f'兄弟，你输入的int转换不了~，错误信息：{e.args}')
    else:
        print(f'{format_n}这个参数没问题~')
        # n必须大于等于0，否则无意义
        if format_n < 0:
            return -1
        else:
            # 如果n为1或者0结果都返回1
            if format_n <= 1:
                return format_n
            for i in range(format_n - 1):
                n2 = n0 + n1
                n0 = n1
                n1 = n2
                format_n -= 1
    finally:
        print('我是for循环的finally!-------------------------------------------------------')
        return n2


# while循环实现  n:斐波那契数列第n项
def fib_while(n):
    n0, n1, n2 = 0, 1, 1
    try:
        format_n = int(n)
    except Exception as e:
        raise ParamsTypeError('报错了兄弟，你输入的int转换不了啊：{}'.format(e.args))
    else:
        print(f'{format_n}这个参数没问题~')
        # n必须大于0，否则无意义
        if format_n < 0:
            print('请输入大于等于0的正整数哦~')
            return -1
        elif format_n <= 1:    # 如果n为0或者1结果都返回1
            return format_n
        while format_n > 1:
            n2 = n0 + n1
            n0 = n1
            n1 = n2
            format_n -= 1
    finally:
        print('我是while循环的finally!-------------------------------------------------------')
        return n2


# 用递归的方式实现斐波那契数列   tag: 日志标志，想看看递归的两个函数怎么执行的
def fib_recursion(n, tag):
    try:
        format_n = int(n)
    except Exception as e:
        raise ParamsTypeError('报错了兄弟，你输入的咱不能转换为int啊：{}'.format(e.args))
    else:
        print(f'{format_n}这个参数没问题~{tag}')
        if format_n < 0:
            print('请输入>=0的正整数哦~')
            return -1
        elif format_n <= 1:
            print('format_n <= 1 进来了')
            return format_n
        return fib_recursion(int(n) - 1, '前') + fib_recursion(int(n) - 2, '后')
    finally:
        pass


if __name__ == '__main__':
    # for调用
    n_for = input('请输入你要计算的斐波那契数列的项数n（for循环计算）:')
    result = fib_for(n_for)
    if result != -1:
        print(f'{n_for}的斐波那契数列结果为(for循环)：{result}')
    else:
        print('请输入>=0的正整数哦~')

    # while调用
    n_while = input('请输入你要计算的斐波那契数列的项数n（while循环计算）:')
    result = fib_while(n_while)
    if result != -1:
        print(f'{n_while}的斐波那契数列结果为(while循环)：{result}')
    else:
        print('请输入>=0的正整数哦~')

    # 递归调用
    n_recursion = input('请输入你要计算的斐波那契数列的项数n（recursion循环计算）:')
    result = fib_recursion(n_recursion, '递归开始')
    if result != -1:
        print(f'{n_recursion}的斐波那契数列结果为(recursion递归)：{result}')
    else:
        print('请输入>=0的正整数哦~')
